package com.mdtx.base.security;

import com.mdtx.base.SystemErrorCode;
import com.mdtx.base.exception.BaseException;
import com.mdtx.base.security.type.AudienceType;
import com.mdtx.base.security.type.SubjectType;
import com.mdtx.utils.LogHelper;
import io.jsonwebtoken.*;
import sun.misc.BASE64Encoder;

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static sun.security.x509.CertificateAlgorithmId.ALGORITHM;

/**
 * token工具
 *
 * @author zhgz
 * @create 2017-08-31 20:28
 **/
public class AccessToken {

    private static final String ISSUSER = "mdtx";

    public static final String TOKEN="mdtx_tk";

    private static final long MAX_EXP = 7 * 24 * 60 * 60 * 1000;

    private static final long EXP = 60 * 1000;

    private static final long MIN_EXP = 30 * 1000;

    private static final String SECRET ="zjs@eZOY@c@Eg%W66g*E7TbWbx9n1@nw";

    public static final int NORMAL = 0;

    public static final int OVERTIME = -1;

    /**
     *
     * @param token 系统生成的token
     * @return
     */
    public static String createAccessTokenPhone(String token){

        JwtBuilder jwt = Jwts.builder()
                .setIssuedAt(new Date())
                .setIssuer(ISSUSER)
                .setSubject(SubjectType.LOGIN)
                .setAudience(AudienceType.PHONE_USER)
                .setExpiration(new Date(System.currentTimeMillis()+MAX_EXP))
                .claim(TOKEN,token)
                .signWith(SignatureAlgorithm.HS256,SECRET);

        return jwt.compact();
    }
    /**
     *
     * @param token 系统生成的token
     * @return
     */
    public static String createAccessTokenPc(String token){

        JwtBuilder jwt = Jwts.builder()
                .setIssuedAt(new Date())
                .setIssuer(ISSUSER)
                .setSubject(SubjectType.LOGIN)
                .setAudience(AudienceType.PC_USER)
                .setExpiration(new Date(System.currentTimeMillis()+MIN_EXP))
                .claim(TOKEN,token)
                .signWith(SignatureAlgorithm.HS256,SECRET);

        return jwt.compact();
    }


    /**
     *
     * @param accesToken 待解析token
     * @return
     */
    public static String pasrseAccessToken(String accesToken){

        Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(accesToken).getBody();

        return claims.get(TOKEN,String.class);

    }

    /**
     * 解析用户类型
     * @param accesToken
     * @return
     */
    public static String pasrseAccessTokenAud(String accesToken){
       return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(accesToken).getBody().getAudience();
    }

    /**
     *
     * @param accesToken 解析token
     * @return
     */
    public static int vlidateAccessToken(String accesToken){

        try {
            Jwts.parser().setSigningKey(SECRET).parseClaimsJws(accesToken).getBody();
        }catch (SignatureException e){
            throw new BaseException(SystemErrorCode.TOKE_INVALID,e);

        }catch (ExpiredJwtException e){
            LogHelper.log(SystemErrorCode.TOKE_OVERTIME.getErrorInfo());
            return OVERTIME;
        }

        return NORMAL;

    }


    public static String generateToke() {


        try {
            SecureRandom random = new SecureRandom();
            byte[] salt = new byte[12];
            random.nextBytes(salt);
            MessageDigest md = MessageDigest.getInstance("MD5");

            md.update(salt);
            md.update(UUID.randomUUID().toString().getBytes("UTF8"));

            byte[] digest = md.digest();
            BASE64Encoder encoder = new BASE64Encoder();
            String saltS = encoder.encode(salt);
            String digestS = encoder.encode(digest);

            return saltS + digestS;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {
            System.out.println(generateToke());
        }

    }


}
